﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace Vbyte.TextReader.Util
{
    /// <summary>
    /// 字符创功能辅助函数
    /// </summary>
    public static class StringHelper
    {
        /// <summary>
        /// 字符块过滤(剔除从前置到后置尾的所有块的新字符Source)
        /// </summary>
        /// <param name="Source">原始字符</param>
        /// <param name="snippet">中间代码片断，以“REGEX:”开头则后续字符视为不区分大小写正则匹配模式。</param>
        /// <param name="strBefore">片断前置字符</param>
        /// <param name="strAfter">片断后置字符</param>
        public static void FilterBlock(ref string Source, string snippet, string strBefore, string strAfter)
        {
            int idx = -1, len = snippet.Length;
            if (snippet.StartsWith("REGEX:"))
            {
                string pattern = snippet.Substring(6);
                MatchCollection mc = Regex.Matches(Source, pattern, RegexOptions.IgnoreCase);
                if (mc.Count > 0)
                {
                    idx = mc[0].Index;
                    len = mc[0].Length;
                }
            }
            else
            {
                idx = Source.IndexOf(snippet);
            }

            if (idx != -1)
            {
                int idxBegin = Source.LastIndexOf(strBefore, idx);
                int idxEnd = Source.IndexOf(strAfter, idx + len);
                if (idxBegin != -1 && idxEnd != -1)
                {
                    len = idxEnd + strAfter.Length - idxBegin;
                    Source = Source.Replace(Source.Substring(idxBegin, len), "");
                }
            }
        }
        
        /// <summary>
        /// 获取正则匹配模式下指定索引的值集合
        /// Revsion: 1.0.0 2007-5-10 Ridge Wong
        /// </summary>
        /// <param name="SourceText">原始字符查找</param>
        /// <param name="Pattern">匹配模式</param>
        /// <param name="IdxesOrNames">相关匹配索引或组名称项</param>
        /// <returns>如果不匹配，则返回对象Null。</returns>
        public static string[] GetPatternMatchValue(string SourceText, string Pattern, params object[] IdxesOrNames)
        {
            if (SourceText == null) return null;

            Match m = Regex.Match(SourceText, Pattern, RegexOptions.IgnoreCase);
            if (!m.Success)
            {
                return null;
            }
            else
            {
                string[] retObjStr = new string[IdxesOrNames.Length];
                for (int i = 0; i < IdxesOrNames.Length; i++)
                {
                    object getM = IdxesOrNames[i];
                    if (getM.GetType() == typeof(int))
                    {
                        if (Convert.ToInt32(getM) < m.Groups.Count)
                        {
                            retObjStr[i] = m.Groups[Convert.ToInt32(getM)].Value;
                        }
                    }
                    else if (getM.GetType() == typeof(string))
                    {
                        if (m.Groups[getM.ToString()] != null)
                        {
                            retObjStr[i] = m.Groups[getM.ToString()].Value;
                        }
                    }

                }
                return retObjStr;
            }
        }

        /// <summary>
        /// 获取特定字符片断字符块
        /// </summary>
        /// <param name="Source">原始字符</param>
        /// <param name="snippet">中间代码片断，以“REGEX:”开头则后续字符视为不区分大小写正则匹配模式。</param>
        /// <param name="strBefore">片断前置字符</param>
        /// <param name="strAfter">片断后置字符</param>
        public static string GetSnippetBlock(ref string Source, string snippet, string strBefore, string strAfter)
        {
            int idx = -1, len = snippet.Length;
            string strReturn = string.Empty;
            int regexIndex = 0, regexCount = 1;
            MatchCollection mc = null;

            if (snippet.StartsWith("REGEX:"))
            {
                string pattern = snippet.Substring(6);
                mc = Regex.Matches(Source, pattern, RegexOptions.IgnoreCase);
                if (mc.Count > 0)
                {
                    regexCount = mc.Count;
                    idx = mc[regexIndex].Index;
                    len = mc[regexIndex].Length;
                }
            }
            else
            {
                idx = Source.IndexOf(snippet);
            }


        FetchNext:

            if (idx != -1)
            {
                int idxBegin = Source.LastIndexOf(strBefore, idx);
                int idxEnd = Source.IndexOf(strAfter, idx + len);
                if (idxBegin != -1 && idxEnd != -1)
                {
                    len = idxEnd + strAfter.Length - idxBegin;
                    strReturn = Source.Substring(idxBegin, len);
                }
                else
                {
                    if (mc != null)
                    {
                        #region 如果有下一组匹配
                        if (regexIndex + 1 < regexCount)
                        {
                            regexIndex++;
                            idx = mc[regexIndex].Index;
                            len = mc[regexIndex].Length;
                            goto FetchNext;
                        }
                        #endregion
                    }
                    else
                    {
                        #region 字符下一个查找
                        idx = Source.IndexOf(snippet, idx + 1);
                        if (idx != -1)
                            goto FetchNext;
                        #endregion
                    }
                }
            }

            return strReturn;
        }

        /// <summary>
        /// 获取文本文件的字符编码
        /// </summary>
        /// <param name="srcFile">文本文件路径</param>
        /// <returns>字符编码</returns>
       public static Encoding GetFileEncoding(string srcFile)
        {
            // *** Use Default of Encoding.Default (Ansi CodePage)
            Encoding enc = Encoding.Default;
            // *** Detect byte order mark if any - otherwise assume default
            byte[] buffer = new byte[5];
            FileStream file = new FileStream(srcFile, FileMode.Open);
            file.Read(buffer, 0, 5);
            file.Close();
            file.Dispose();

            if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
                enc = Encoding.UTF8;
            else if (buffer[0] == 0xfe && buffer[1] == 0xff)
                enc = Encoding.Unicode;
            else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
                enc = Encoding.UTF32;
            else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
                enc = Encoding.UTF7;
            return enc;
        }

    }
}
